#ifndef NIDHOGGR_H
#define NIDHOGGR_H

#include <set>
#include <vector>
#include <queue>
#include "OString.h"
#include "Texture.h"
#include "TextureBlock.h"
#include "Font.h"

namespace Y{

class Entity;
class Widget;
class Compositor;

class Nidhoggr{
	
	public:
		
		std::set< Entity* > entities;
		std::set< Widget* > widgets;
		
		//Path variables
		OString executablePath;
		OString resourcePath;
		
		//Event Variables
		Vertex2f lastMouse;
		int mouseButton;
		int keyModifiers;
		int counter;
		
		//State Variables
		bool openGLInitialized;
		
		//General Variables
		double pixelWidth;
		double pixelHeight;
		double openGLWidth;
		double openGLHeight;
		
		//Widget Variables
		Widget * focusedWidget;
		Widget * lastClickedWidget;
		Widget * mousedOverWidget;
		Widget * draggingWidget;
		std::map < OString, Widget * > defaultWidgets;
		std::map < int, Entity * > entityIDmap;
		
		std::deque< Entity * > releaseQ;
		
		//Command line arguments
		std::vector< OString > args;
		
		//Texture data
		std::map < OString,Texture > textureStorage;
			std::map < GLuint,Texture* > textureStorage_id_to_texture;
			std::map < GLuint,OString	> textureStorage_id_to_name;
			std::map < OString,Texture* > textureStorage_path_to_texture;
			Texture * emptyTexture;
			Texture * zeroTexture;
		std::map < OString,TextureBlock* > textureBlockStorage;
		std::map < OString,Font > fonts;
			Font * currentFont;
			Compositor * compositor;
			
		bool texturesInitialized;
		bool widgetsInitialized;
	public:
	
		Nidhoggr ();
		virtual ~Nidhoggr() {}
		
		
		void arg (int argc, char *argv[] );
		virtual void initialize ( std::vector< OString >& );
		virtual void initTextures ();
		virtual void initWidgets ();
		virtual void initCompositor ();
		//OpenGL Functions
		void initGL ();
		void resizeGL (float,float);
		virtual void paintGL ();
		virtual void selectionPaintGL ();
		//State change functions
		void resize (double w,double h);
		//Event Functions
		virtual void mousePress(int x, int y);
		virtual void mouseRelease(int x, int y);
		virtual void mouseMove(int x, int y);
		virtual void mouseDrag(int x, int y);
			GLuint selection(int x, int y, int mode = 0, void (Nidhoggr::*p) () = NULL);
		virtual void scrollWheel(float dx,float dy,float dz); 
		virtual void keyPress(unsigned char c, int mod);
		virtual void keyRelease(unsigned char c, int mod);
		int	 getKeyModifiers() const;
		
		void changeFocusedWidget( Widget * );
		void changeDraggingWidget( Widget * );
		
		void subTimer(float x);
		virtual void timer (float x);
		//Texture Functions
		
		void firstRites (Entity *e);
		void lastRites	(Entity *e);
		
		void firstRites (Widget *w);
		void lastRites	(Widget *w);
		
		Texture* loadTexture ( const OString& name, const OString& path, bool keep );
		Texture* loadTextureForTextureBlock ( const OString& name, const OString& path );
		Texture* getTexture ( const OString& name );
		Texture* getTexture ( GLuint ID );
		
//		static Nidhoggr * app_ptr;
};

//#define App Y::Nidhoggr::app_ptr

}

#endif